package com.obggtc.picture.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Redis工具类使用示例
 * 项目中的各种Redis工具类
 */
@Component
public class RedisExampleUsage {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private JwtCacheUtils jwtCacheUtils;

    @Autowired
    private ImageCacheUtils imageCacheUtils;

    @Autowired
    private RedisLockUtils redisLockUtils;

    @Autowired
    private RedisRateLimiterUtils rateLimiterUtils;

    /**
     * 基础Redis操作示例
     */
    public void basicRedisOperations() {
        // 1. 字符串操作
        redisUtils.set("user:name", "张三", 3600); // 缓存1小时
        String name = (String) redisUtils.get("user:name");
        
        // 2. 哈希操作
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("name", "张三");
        userInfo.put("age", 25);
        userInfo.put("email", "zhangsan@example.com");
        redisUtils.hmset("user:info:1", userInfo, 3600);
        
        // 3. 列表操作
        redisUtils.lSet("user:recent:actions", "登录");
        redisUtils.lSet("user:recent:actions", "上传图片");
        redisUtils.lSet("user:recent:actions", "查看图片");
        
        // 4. 集合操作
        redisUtils.sSet("user:permissions", "READ", "WRITE", "DELETE");
        
        // 5. 计数器
        long viewCount = redisUtils.incr("page:view:count", 1);
    }

    /**
     * JWT缓存使用示例
     */
    public void jwtCacheExample() {
        String username = "testuser";
        String token = "eyJhbGciOiJIUzI1NiJ9..."; // 示例token
        
        // 1. 缓存token信息
        jwtCacheUtils.cacheTokenInfo(token, username, 86400); // 24小时
        
        // 2. 缓存用户活跃token
        jwtCacheUtils.cacheUserToken(username, token, 86400);
        
        // 3. 检查token是否有效（包括黑名单检查）
        boolean isValid = jwtCacheUtils.isTokenValid(token);
        
        // 4. 用户登出
        if (isValid) {
            jwtCacheUtils.logout(token, username);
        }
        
        // 5. 强制用户下线
        jwtCacheUtils.forceLogout(username);
        
        // 6. 刷新token管理
        String refreshToken = "refresh_token_example";
        jwtCacheUtils.cacheRefreshToken(username, refreshToken, 604800); // 7天
    }

    /**
     * 图片缓存使用示例
     */
    public void imageCacheExample() {
        String imageId = "img_123456";
        String username = "testuser";
        
        // 1. 缓存图片基本信息
        Map<String, Object> imageInfo = new HashMap<>();
        imageInfo.put("fileName", "sunset.jpg");
        imageInfo.put("fileSize", "2048000");
        imageInfo.put("fileType", "image/jpeg");
        imageInfo.put("uploadTime", System.currentTimeMillis());
        imageCacheUtils.cacheImageInfo(imageId, imageInfo);
        
        // 2. 增加访问次数
        long viewCount = imageCacheUtils.incrementViewCount(imageId);
        
        // 3. 添加到用户图片列表
        imageCacheUtils.addUserImage(username, imageId);
        
        // 4. 缓存图片标签
        List<String> tags = Arrays.asList("风景", "日落", "自然");
        imageCacheUtils.cacheImageTags(imageId, tags);
        
        // 5. 添加到最近上传列表
        imageCacheUtils.addToRecentUploads(imageId);
        
        // 6. 添加到热门图片（基于访问量计算热度分数）
        double hotScore = viewCount * 1.0 + tags.size() * 0.1;
        imageCacheUtils.addToHotImages(imageId, hotScore);
        
        // 7. 缓存缩略图信息
        imageCacheUtils.cacheThumbnailInfo(imageId, "/thumbnails/img_123456_thumb.jpg", "150x150");
    }

    /**
     * 分布式锁使用示例
     */
    public void distributedLockExample() {
        String filename = "important_file.jpg";
        String username = "testuser";
        String imageId = "img_123456";
        
        // 1. 文件上传锁
        String uploadLock = redisLockUtils.tryFileUploadLock(filename);
        if (uploadLock != null) {
            try {
                // 执行文件上传逻辑
                System.out.println("正在上传文件: " + filename);
                Thread.sleep(2000); // 模拟上传耗时
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                redisLockUtils.unlock("file:upload:" + filename, uploadLock);
            }
        }
        
        // 2. 用户操作锁
        String userLock = redisLockUtils.tryUserOperationLock(username, "delete_image");
        if (userLock != null) {
            try {
                // 执行删除图片逻辑
                System.out.println("用户 " + username + " 正在删除图片");
            } finally {
                redisLockUtils.unlock("user:operation:" + username + ":delete_image", userLock);
            }
        }
        
        // 3. 使用锁执行业务逻辑（推荐方式）
        try {
            String result = redisLockUtils.executeWithLock("image:process:" + imageId, () -> {
                // 图片处理逻辑
                System.out.println("正在处理图片: " + imageId);
                return "处理完成";
            });
            System.out.println(result);
        } catch (Exception e) {
            System.out.println("获取锁失败或处理异常: " + e.getMessage());
        }
    }

    /**
     * 限流使用示例
     */
    public void rateLimiterExample() {
        String userIp = "192.168.1.100";
        String username = "testuser";
        String apiPath = "/api/upload";
        
        // 1. IP限流 - 每分钟最多10次请求
        boolean ipAllowed = rateLimiterUtils.isAllowedByIP(userIp, 10, 60);
        if (!ipAllowed) {
            System.out.println("IP访问频率过高，请稍后再试");
            return;
        }
        
        // 2. 用户限流 - 每小时最多100次请求
        boolean userAllowed = rateLimiterUtils.isAllowedByUser(username, 100, 3600);
        if (!userAllowed) {
            System.out.println("用户请求频率过高，请稍后再试");
            return;
        }
        
        // 3. API接口限流 - 每分钟最多50次请求
        boolean apiAllowed = rateLimiterUtils.isAllowedByAPI(apiPath, 50, 60);
        if (!apiAllowed) {
            System.out.println("API访问频率过高，请稍后再试");
            return;
        }
        
        // 4. 文件上传限流 - 每小时最多20次上传
        boolean uploadAllowed = rateLimiterUtils.isUploadAllowed(username, 20, 3600);
        if (!uploadAllowed) {
            System.out.println("上传频率过高，请稍后再试");
            return;
        }
        
        // 5. 登录尝试限流 - 每5分钟最多5次尝试
        boolean loginAllowed = rateLimiterUtils.isLoginAllowed(userIp, 5, 300);
        if (!loginAllowed) {
            System.out.println("登录尝试次数过多，请稍后再试");
            return;
        }
        
        // 6. 滑动窗口限流
        RedisRateLimiterUtils.RateLimitResult result = 
            rateLimiterUtils.isAllowedSlidingWindow("api:sensitive", 10, 60);
        if (!result.isAllowed()) {
            System.out.println("请求被限流，当前请求数: " + result.getCurrentCount() + 
                             ", 剩余: " + result.getRemaining());
            return;
        }
        
        // 7. 令牌桶限流
        RedisRateLimiterUtils.TokenBucketResult tokenResult = 
            rateLimiterUtils.isAllowedTokenBucket("api:token", 100, 10, 1000, 1);
        if (!tokenResult.isAllowed()) {
            System.out.println("令牌不足，剩余令牌: " + tokenResult.getRemainingTokens());
            return;
        }
        
        System.out.println("所有限流检查通过，可以处理请求");
    }

    /**
     * 综合使用示例：文件上传场景
     */
    public void fileUploadScenario(String username, String filename) {
        // 1. 限流检查
        if (!rateLimiterUtils.isUploadAllowed(username, 20, 3600)) {
            throw new RuntimeException("上传频率过高，请稍后再试");
        }
        
        // 2. 获取上传锁
        String lockValue = redisLockUtils.tryFileUploadLock(filename);
        if (lockValue == null) {
            throw new RuntimeException("文件正在被其他用户上传，请稍后再试");
        }
        
        try {
            // 3. 执行上传逻辑
            String imageId = "img_" + System.currentTimeMillis();
            
            // 4. 缓存图片信息
            Map<String, Object> imageInfo = new HashMap<>();
            imageInfo.put("fileName", filename);
            imageInfo.put("uploader", username);
            imageInfo.put("uploadTime", System.currentTimeMillis());
            imageCacheUtils.cacheImageInfo(imageId, imageInfo);
            
            // 5. 添加到用户图片列表
            imageCacheUtils.addUserImage(username, imageId);
            
            // 6. 添加到最近上传列表
            imageCacheUtils.addToRecentUploads(imageId);
            
            System.out.println("文件上传成功: " + imageId);
            
        } finally {
            // 7. 释放锁
            redisLockUtils.unlock("file:upload:" + filename, lockValue);
        }
    }
} 